package org.millioncall.yueyoga.admin.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.millioncall.openplatform.util.DateTimeUtils;
import org.millioncall.openplatform.util.NumberUtils;
import org.millioncall.yueyoga.admin.dao.CheduleDetailsDAO;
import org.millioncall.yueyoga.admin.dao.ConsumptionDAO;
import org.millioncall.yueyoga.admin.dao.MemberClazzDAO;
import org.millioncall.yueyoga.admin.dao.MemberDAO;
import org.millioncall.yueyoga.admin.dao.ProductRemainingDAO;
import org.millioncall.yueyoga.admin.dao.RemainingDAO;
import org.millioncall.yueyoga.admin.dao.ReservationDAO;
import org.millioncall.yueyoga.admin.model.CheduleDetails;
import org.millioncall.yueyoga.admin.model.Clazz;
import org.millioncall.yueyoga.admin.model.Coach;
import org.millioncall.yueyoga.admin.model.Consume;
import org.millioncall.yueyoga.admin.model.Member;
import org.millioncall.yueyoga.admin.model.MemberClazz;
import org.millioncall.yueyoga.admin.model.Place;
import org.millioncall.yueyoga.admin.model.Product;
import org.millioncall.yueyoga.admin.model.ProductRemaining;
import org.millioncall.yueyoga.admin.model.Remaining;
import org.millioncall.yueyoga.admin.model.Reservation;
import org.millioncall.yueyoga.admin.model.User;
import org.millioncall.yueyoga.admin.model.WeeklyUseTimes;
import org.millioncall.yueyoga.admin.service.ReservationService;
import org.springframework.stereotype.Service;

@Service
public class ReservationServiceImpl implements ReservationService {

	private ReservationDAO reservationDAO;
	private MemberDAO memberDAO;
	private RemainingDAO remainingDAO;
	private ConsumptionDAO consumptionDAO;
	private MemberClazzDAO memberClazzDAO;
	private CheduleDetailsDAO cheduleDetailsDAO;
	private ProductRemainingDAO productRemainingDAO;

	@Override
	public int update(Reservation reservation) {
		return reservation != null ? reservationDAO.update(reservation) : 0;
	}

	@Override
	public int saveReservation(Reservation reservation) {
		return reservation != null ? reservationDAO
				.saveReservation(reservation) : 0;
	}

	@Override
	public List<Reservation> findReservationByMap(Map<String, Object> maps) {
		return reservationDAO.findReservationByMap(maps);
	}

	public ReservationDAO getReservationDAO() {
		return reservationDAO;
	}

	public void setReservationDAO(ReservationDAO reservationDAO) {
		this.reservationDAO = reservationDAO;
	}

	public MemberDAO getMemberDAO() {
		return memberDAO;
	}

	public void setMemberDAO(MemberDAO memberDAO) {
		this.memberDAO = memberDAO;
	}

	public RemainingDAO getRemainingDAO() {
		return remainingDAO;
	}

	public void setRemainingDAO(RemainingDAO remainingDAO) {
		this.remainingDAO = remainingDAO;
	}

	public ConsumptionDAO getConsumptionDAO() {
		return consumptionDAO;
	}

	public void setConsumptionDAO(ConsumptionDAO consumptionDAO) {
		this.consumptionDAO = consumptionDAO;
	}

	public CheduleDetailsDAO getCheduleDetailsDAO() {
		return cheduleDetailsDAO;
	}

	public void setCheduleDetailsDAO(CheduleDetailsDAO cheduleDetailsDAO) {
		this.cheduleDetailsDAO = cheduleDetailsDAO;
	}

	public ProductRemainingDAO getProductRemainingDAO() {
		return productRemainingDAO;
	}

	public void setProductRemainingDAO(ProductRemainingDAO productRemainingDAO) {
		this.productRemainingDAO = productRemainingDAO;
	}

	public MemberClazzDAO getMemberClazzDAO() {
		return memberClazzDAO;
	}

	public void setMemberClazzDAO(MemberClazzDAO memberClazzDAO) {
		this.memberClazzDAO = memberClazzDAO;
	}

	@Override
	public List<Reservation> findReservationByCdts(Map<String, Object> map) {
		return reservationDAO.findReservationByCdts(map);
	}

	@Override
	public boolean reservateSingleSeat(String ydId, String memberId) {
		Reservation reservation = new Reservation();
		reservation.setLastModifyTime(new Date());
		reservation.setId(Integer.valueOf(ydId));
		reservation.setMemberId(Integer.valueOf(memberId));
		return reservationDAO.updateByReservation(reservation);
	}

	@Override
	public boolean cancelReservation(String reservateId) {
		if (StringUtils.isNotBlank(reservateId)) {
			return reservationDAO.cancelReservation(Integer
					.valueOf(reservateId));
		}
		return false;
	}

	@Override
	public List<String> findTwoWeekDate() {
		// --获取当前日期实例
		Calendar c = null;
		String date = "";
		List<String> list = new ArrayList<String>();
		for (int i = 0; i < 14; i++) {
			c = Calendar.getInstance();
			c.setFirstDayOfWeek(Calendar.MONDAY);
			// --获取本周周一的日期
			c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
			c.add(Calendar.DAY_OF_MONTH, i);
			date = DateTimeUtils.getInstance()
					.format(c.getTime(), "yyyy-MM-dd");
			date = date.substring(5, date.length());
			list.add(date);
		}
		return list;
	}

	@Override
	public boolean reservateSchedule(String scheId, String memberId) {
		Reservation reservation = new Reservation();
		reservation.setLastModifyTime(new Date());
		if (StringUtils.isBlank(scheId)) {
			return false;
		}
		Integer scheduleId = Integer.valueOf(scheId);
		Integer resvId = reservationDAO.findNextResvId(scheduleId);
		reservation.setId(resvId);
		reservation.setScheduleId(scheduleId);
		reservation.setMemberId(Integer.valueOf(memberId));
		return reservationDAO.updateByReservation(reservation);
	}

	@Override
	public int resvSchedule(String scheId, String memberId) {
		// --return -1:预约失败，1:预约成功，2:已存在预约会员 3.超过产品的周预约限制

		Reservation reservation = new Reservation();
		reservation.setLastModifyTime(new Date());
		// --查询是否重复预约课程
		if (reservationDAO.findResvCountByScheIdAndMemberId(scheId, memberId) > 0) {
			return 2;
		}
		Integer scheduleId = Integer.valueOf(scheId);
		Integer resvId = reservationDAO.findNextResvId(scheduleId);
		reservation.setId(resvId);
		reservation.setScheduleId(scheduleId);
		reservation.setMemberId(Integer.valueOf(memberId));
		// 判断是否已超出周使用限制
		WeeklyUseTimes wut = this.reservationDAO
				.getMemberWeeklyUseTimes(Integer.valueOf(memberId));
		if (wut.getLimitOfWeek() == null || wut.getLimitOfWeek() <= 0) {
			// do nothing...
		} else {
			if (wut.getWeeklyUseTimes() >= wut.getLimitOfWeek()) {
				return 3;// 超过产品的周预约限制
			}
		}

		// 设置每周使用次数
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("memberId", memberId);
		params.put("count", wut.getWeeklyUseTimes() + 1);
		reservationDAO.setProductWeeklyUseTimes(params);
		return reservationDAO.updateByReservation(reservation) ? 1 : -1;
	}

	@Override
	public boolean cancelResvSchedule(String scheduleId, String memberId) {
		Reservation reservation = reservationDAO
				.findResvScheduleInfoByScheIdAndMemberId(scheduleId, memberId);
		if (reservation == null) {
			return false;
		}

		// 判断是否已超出周使用限制
		WeeklyUseTimes wut = this.reservationDAO
				.getMemberWeeklyUseTimes(Integer.valueOf(memberId));

		// 设置每周使用次数
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("memberId", memberId);
		params.put("count", wut.getWeeklyUseTimes() - 1);
		reservationDAO.setProductWeeklyUseTimes(params);
		return reservationDAO.cancelReservation(reservation.getId());
	}

	@Override
	public String attendSchedule(String resvId, Integer prId, User user) {
		Map<String, Object> map = new HashMap<String, Object>();
		String msg = "{\"success\":false,\"msg\":\"出席失败\"}";
		Integer resId = Integer.valueOf(resvId);
		Reservation resv = reservationDAO.findReservationById(resId);
		// 课程编号
		Integer scheduleId = resv.getScheduleId();
		// --会员编号
		Integer memberId = resv.getMemberId();
		// --会员产品编号
		resv.setState("是");
		resv.setLastModifyTime(new Date());
		map.put("scheduleId", scheduleId);

		// --获取课程信息
		CheduleDetails cd = cheduleDetailsDAO.findCheduleDetailById(map);
		// -- 获得班级信息
		Clazz clazz = cd.getClazz();
		// --获得场地信息
		Place place = cd.getPlace();
		// --获得老师信息
		Coach teacher = cd.getTeacher();
		// --获得助教信息
		Coach assistant = cd.getAssistant();
		map.put("scheduleId", scheduleId);
		map.put("memberId", memberId);
		// --获得会员的产品

		ProductRemaining pr = productRemainingDAO
				.findProductRemainingById(prId);
		Product pro = pr.getProduct();

		// 次卡
		if (101 == pro.getType()) {
			// 获得剩余产品的可用次数
			int count = pr.getCounts();
			if (count <= 0) {
				return "{\"success\":false,\"msg\":\"次卡次数已不足\"}";
			}
		} else if (107 == pro.getType() || 108 == pro.getType()) { // 此状态单独消费该产品类型
			Remaining remaining = remainingDAO.findById(memberId);
			Double money = remaining.getRemaining();
			Double proPrice = pr.getProduct().getPrice();
			// 金额计算
			money = NumberUtils.sub(money, proPrice);
			if (money < 0) {
				return "{\"success\":false,\"msg\":\"您的金额已不足,请及时充值\"}";
			}
		}

		// --获得会员信息
		map.put("id", memberId);
		map.put("hallCode", user.getOrganizationId());
		map.put("hallcode", user.getOrganizationId());
		Member member = memberDAO.findById(map);
		Consume con = new Consume();
		Calendar cdr = Calendar.getInstance();
		// --星期
		int week = cdr.get(Calendar.DAY_OF_WEEK) - 1;
		if (0 == week) {
			week = 7;
		}
		con.setWeek(week);
		con.setClazz(clazz);
		con.setClazzId(clazz.getId());
		con.setClazzName(clazz.getName());
		con.setConsumeTime(new Date());
		con.setCreatedBy(user);
		con.setCreatedById(user.getId());
		con.setCreateTime(new Date());
		con.setInputTime(new Date());
		con.setMember(member);
		con.setMemberId(member.getMemberid());
		con.setMemberName(member.getName());
		con.setPlace(place);
		con.setPlaceId(place.getId());
		con.setPlaceName(place.getName());

		con.setProduct(pro);
		con.setProductId(pro.getProductId());
		con.setProductName(pro.getName());

		if (assistant != null) {
			con.setScheduleAssistant(assistant);
			con.setScheduleAssistantId(assistant.getCoachId());
			con.setScheduleAssistantName(assistant.getName());
		}

		con.setScheduleEndTime(cd.getEndtime());
		con.setScheduleId(cd.getId());
		con.setScheduleStartTime(cd.getStarttime());
		if (teacher != null) {
			con.setScheduleTeacher(teacher);
			con.setScheduleTeacherId(teacher.getCoachId());
			con.setScheduleTeacherName(teacher.getName());
		}

		con.setIsReservation(1);
		// 是否是固定会员班级
		if ("固定会员".equals(clazz.getType())) {
			// 如果是，看该会员是否属于该班级
			Map<String, Object> mapMC = new HashMap<String, Object>();
			mapMC.put("memberId", memberId);
			mapMC.put("classId", clazz.getId());
			List<MemberClazz> list = memberClazzDAO
					.findAllMemberInThisClazz(mapMC);
			if (list.size() <= 0) {
				return "{\"success\":false,\"msg\":\"会员不在班级内\"}";
			}
		}
		boolean b = this.consumptionDAO.saveConsume(con);
		if (!b) {
			return "{\"success\":false,\"msg\":\"添加消费记录失败\"}";
		}
		// 次卡
		if (101 == pro.getType()) {
			// 获得剩余产品的可用次数
			int count = pr.getCounts();
			count--;
			int flag = productRemainingDAO.updateCounts(pr.getId(), count);
			if (flag <= 0) {
				return "{\"success\":true,\"msg\":\"次卡数量更新失败\"}";
			}
		} else if (107 == pro.getType() || 108 == pro.getType()) { // 此状态单独消费该产品类型
			Remaining remaining = remainingDAO.findById(memberId);
			Double money = remaining.getRemaining();
			Double proPrice = pr.getProduct().getPrice();
			// 金额计算
			money = NumberUtils.sub(money, proPrice);
			remaining.setRemaining(money);
			remainingDAO.updateRemainingById(remaining);
		}
		// 修改会员状态
		if (!"0021".equals(member.getSubstatus())) {
			member.setSubstatus("0021");
			if (memberDAO.update(member) < 1) {
				return "{\"success\": false, \"msg\": \"更新会员状态失败\"}";
			}
		}

		// --订座表信息更新
		if (reservationDAO.updateByReservation(resv)) {
			msg = "{\"success\": true, \"msg\": \"课程出席成功\"}";
		}
		return msg;
	}

	@Override
	public boolean cancelAttendSchedule(String resvId, Integer prId) {
		Reservation resv = reservationDAO.findReservationById(Integer
				.valueOf(resvId));
		resv.setId(Integer.valueOf(resvId));
		// --会员编号
		Integer memberId = resv.getMemberId();
		resv.setMemberId(null);
		resv.setState("否");
		resv.setLastModifyTime(new Date());
		Integer cheduleId = resv.getScheduleId();

		// -------------------------------------------------------------
		ProductRemaining pr = productRemainingDAO
				.findProductRemainingById(prId);
		Product pro = pr.getProduct();
		// 次卡
		if (101 == pro.getType()) {
			// 获得剩余产品的可用次数
			int count = pr.getCounts();
			count++;
			int flag = productRemainingDAO.updateCounts(pr.getId(), count);
			if (flag <= 0) {
				return false;
			}
		} else if (107 == pro.getType() || 108 == pro.getType()) { // 此状态单独消费该产品类型
			Remaining remaining = remainingDAO.findById(memberId);
			Double money = remaining.getRemaining();
			Double proPrice = pr.getProduct().getPrice();
			// 金额计算
			money = NumberUtils.add(money, proPrice);
			remaining.setRemaining(money);
			remainingDAO.updateRemainingById(remaining);
		}

		String curDate = DateTimeUtils.getInstance().format(new Date(),
				"yyyy-MM-dd");
		// --删除消费记录
		Consume consume = consumptionDAO.findConsumptionByCdts(memberId,
				cheduleId, curDate);
		if (consume != null && consume.getId() != null) {
			consumptionDAO.deleteConsumeById(consume.getId());
		}
		// -------------------------------------------------------------
		return reservationDAO.updateByReservation(resv);
	}

	@Override
	public int cancelReserve(Map<String, Object> map) {
		return this.reservationDAO.cancelReserve(map);
	}

	@Override
	public Reservation findResvScheduleInfoByScheIdAndMemberId(String kcxh,
			String memberId) {
		Reservation reservation = reservationDAO
				.findResvScheduleInfoByScheIdAndMemberId(kcxh, memberId);
		return reservation;
	}

	/***
	 * 离店并创建消费记录
	 */
	/*
	 * public String updateForLeaveHall(User user, String memberId, String
	 * productId, String resvId) { Integer resId = Integer.valueOf(resvId);
	 * Reservation resv = reservationDAO.findReservationById(resId); Map<String,
	 * Object> map = new HashMap<String, Object>(); // 课程编号 Integer scheduleId =
	 * resv.getScheduleId(); map.put("scheduleId", scheduleId);
	 * 
	 * // 判断几天有没有来上过课 Map<String, Object> mapConsumed = new HashMap<String,
	 * Object>(); mapConsumed.put("memberId", memberId);
	 * mapConsumed.put("scheduleId", scheduleId); mapConsumed.put("now", new
	 * Date()); mapConsumed.put("isReservation", 1); boolean consumed =
	 * consumptionDAO.isConsumed(mapConsumed); if (!consumed) {
	 * 
	 * 
	 * // --获取课程信息 CheduleDetails cd =
	 * cheduleDetailsDAO.findCheduleDetailById(map); // -- 获得班级信息 Clazz clazz =
	 * cd.getClazz(); // --获得场地信息 Place place = cd.getPlace(); // --获得老师信息 Coach
	 * teacher = cd.getTeacher(); // --获得助教信息 Coach assistant =
	 * cd.getAssistant(); map.put("memberId", memberId); map.put("productId",
	 * productId); // --获得会员的产品 ProductRemaining pr =
	 * productRemainingDAO.findProductRemainingByHyCpId(map); Product pro =
	 * pr.getProduct(); Date date = new Date(); // 次卡 if (101 == pro.getType())
	 * { // 获得剩余产品的可用次数 int count = pr.getCounts(); if (count <= 0) { return
	 * "{'success':false,'msg':'次卡次数已不足!'}"; } count--; int flag =
	 * productRemainingDAO.updateCounts(pr.getId(), count); if (flag <= 0) {
	 * return "{'success':true,'msg':'次卡数量更新失败!'}"; } } else if (107 ==
	 * pro.getType() || 108 == pro.getType()) { // 此状态单独消费该产品类型 Remaining
	 * remaining = remainingDAO.findById(Integer.valueOf(memberId)); Double
	 * money = remaining.getRemaining(); Double proPrice =
	 * pr.getProduct().getPrice(); // 金额计算 money = NumberUtils.sub(money,
	 * proPrice); if (money <= 0) { return
	 * "{'success':false,'msg':'您的金额已不足,请及时充值!'}"; } else {
	 * remaining.setRemaining(money);
	 * remainingDAO.updateRemainingById(remaining); } }
	 * 
	 * // --获得会员信息 map.put("id", memberId); map.put("hallcode",
	 * user.getOrganizationId()); Member member = memberDAO.findById(map);
	 * Consume con = new Consume(); Calendar cdr = Calendar.getInstance(); //
	 * --星期 int week = cdr.get(Calendar.DAY_OF_WEEK) - 1; if (0 == week) { week
	 * = 7; } con.setWeek(week); con.setClazz(clazz);
	 * con.setClazzId(clazz.getId()); con.setClazzName(clazz.getName());
	 * con.setConsumeTime(new Date()); con.setCreatedBy(user);
	 * con.setCreatedById(user.getId()); con.setCreateTime(new Date());
	 * con.setInputTime(new Date()); con.setMember(member);
	 * con.setMemberId(member.getMemberid());
	 * con.setMemberName(member.getName()); con.setPlace(place);
	 * con.setPlaceId(place.getId()); con.setPlaceName(place.getName());
	 * 
	 * con.setProduct(pro); con.setProductId(pro.getProductId());
	 * con.setProductName(pro.getName()); con.setScheduleAssistant(assistant);
	 * con.setScheduleAssistantId(assistant.getCoachId());
	 * con.setScheduleAssistantName(assistant.getName());
	 * con.setScheduleEndTime(cd.getEndtime()); con.setScheduleId(cd.getId());
	 * con.setScheduleStartTime(cd.getStarttime());
	 * con.setScheduleTeacher(teacher);
	 * con.setScheduleTeacherId(teacher.getCoachId());
	 * con.setScheduleTeacherName(teacher.getName()); con.setIsReservation(1);
	 * // 是否是固定会员班级 if ("固定会员".equals(clazz.getType())) { // 如果是，看该会员是否属于该班级
	 * Map<String, Object> mapMC = new HashMap<String, Object>();
	 * mapMC.put("memberId", memberId); mapMC.put("classId", clazz.getId());
	 * List<MemberClazz> list = memberClazzDAO.findAllMemberInThisClazz(mapMC);
	 * 
	 * } boolean b = this.consumptionDAO.saveConsume(con); if (!b) { return
	 * "{'success':false, 'msg':'添加消费记录失败!'}"; }
	 * 
	 * // 修改会员状态 if (!"0021".equals(member.getSubstatus())) {
	 * member.setSubstatus("0021"); if (memberDAO.update(member) < 1) { return
	 * "{'success': false, 'msg': '更新会员状态失败!'}"; } } return resvId; }
	 */
}
